#include <iostream>
#include "SnakeGameV1.h"
#include <SDL.h>
#include <cmath>
#include <vector>
namespace sg
{

    // 枚举
    // 0 = empty, 1 = snake, 2 = food
    enum
    {
        EMPTY = 0,
        SNAKE = 1,
        FOOD = 2,
    };

    // 方向
    enum Direction
    {
        up,
        down,
        left,
        right,
    };
    // 游戏引擎实例对象
    GameEngine *ge = nullptr;
    // 一个点的像素的宽度和高度
    int wh = 10;
    // 地图大小
    int map[50][50]; // 0 = empty, 1 = snake, 2 = food
                     // 食物的坐标x,y
    struct food
    {
        int x;
        int y;
    } food;
    struct snake_node
    {
        int x;
        int y;
    };

    // 移动速度
    int speed = 50;
    // 蛇的坐标x
    int snake_x = 25;
    // 蛇的坐标y
    int snake_y = 25;
    // 初始化方向
    Direction direction = right;
    std::vector<snake_node> snake_path;

    void init_()
    {
        std::cout << "init()" << std::endl;
        speed = 50;
        snake_x = 25;
        snake_y = 25;
        direction = right;
        snake_path.clear();
        for (size_t i = 0; i < 50; i++)
        {
            for (size_t j = 0; j < 50; j++)
            {
                map[i][j] = 0;
            }
        }
        // snake
        map[snake_x][snake_y] = SNAKE;
    }

    void init_food()
    {
        while (1)
        {
            // 生成食物
            int x = rand() % 50;
            int y = rand() % 50;
            if (map[x][y] == EMPTY)
            {
                // 清除食物
                map[food.x][food.y] = EMPTY;
                // 生成食物
                food.x = x;
                food.y = y;
                map[food.x][food.y] = FOOD;
                break;
            }
        }
    }

    void game_over()
    {
        std::cout << "game over" << std::endl;
        
        init_();
        init_food();

        
    }

    void SnakeGameV1::play()
    {
        ge = this;
        std::cout << "SnakeGameV1 play()" << std::endl;
        // 设置默认场景
        this->setScene(new MainScene());
        init_();
        init_food();
        // 进入游戏循环
        this->run();
    }

    // 主要场景
    void MainScene::handleEvent(SDL_Event &event)
    {

        if (event.type == SDL_KEYDOWN)
        {
            switch (event.key.keysym.sym)
            {
            case SDLK_UP:
                std::cout << "up" << std::endl;
                if (direction != down)
                {
                    direction = up;
                }
                break;
            case SDLK_DOWN:
                std::cout << "down" << std::endl;
                if (direction != up)
                {
                    direction = down;
                }
                break;
            case SDLK_LEFT:
                std::cout << "left" << std::endl;
                if (direction != right)
                {
                    direction = left;
                }
                break;
            case SDLK_RIGHT:
                std::cout << "right" << std::endl;
                if (direction != left)
                {
                    direction = right;
                }
                break;
            case SDLK_KP_SPACE:
                // 游戏暂停

                break;
            default:
                break;
            }
        }
    }
    void MainScene::update()
    {
        // std::cout << "FPS:" << ge->getCurrentFPS() << std::endl;
        static Uint32 lastTime = SDL_GetTicks();
        Uint32 currentTime = SDL_GetTicks();
        Uint32 elapsedTime = currentTime - lastTime;
        if (elapsedTime >= speed)
        {
            int x = snake_x;
            int y = snake_y;
            bool eated = false;
            if (direction == up)
            {
                snake_y--;
            }
            else if (direction == down)
            {
                snake_y++;
            }
            else if (direction == left)
            {
                snake_x--;
            }
            else if (direction == right)
            {
                snake_x++;
            }

            // 判断是否越界
            if (snake_x < 0 || snake_x >= 50 || snake_y < 0 || snake_y >= 50)
            {
                game_over();
                return;
            }

            if (map[snake_x][snake_y] == FOOD)
            {
                std::cout << "eat food" << std::endl;
                eated = true;
                init_food();
            }
            else if (map[snake_x][snake_y] == SNAKE)
            {
                game_over();
                return;
            }

            if (!eated)
            {
                if (snake_path.size() > 0)
                {
                    map[snake_path[0].x][snake_path[0].y] = EMPTY;
                    snake_path.erase(snake_path.begin());
                }
            }
            else
            {
                if (speed > 10)
                {
                    speed -= 2;
                }
            }
            snake_path.push_back({x, y});
            map[snake_x][snake_y] = SNAKE;
            for (auto &&i : snake_path)
            {
                map[i.x][i.y] = SNAKE;
            }
            lastTime = currentTime;
        }
    }
    void MainScene::render()
    {
        for (int i = 0; i < 50; i++)
        {
            for (int j = 0; j < 50; j++)
            {
                SDL_Rect rect{
                    wh * i,
                    wh * j,
                    wh,
                    wh};

                int v = map[i][j];
                if (v == EMPTY)
                {
                    SDL_SetRenderDrawColor(ge->getRenderer(), 229, 229, 229, 255);
                    SDL_RenderDrawRect(ge->getRenderer(), &rect);
                }
                if (v == SNAKE)
                {
                    SDL_SetRenderDrawColor(ge->getRenderer(), 3, 169, 244, 255);
                    SDL_RenderFillRect(ge->getRenderer(), &rect);
                }

                if (v == FOOD)
                {
                    SDL_SetRenderDrawColor(ge->getRenderer(), 238, 76, 76, 255);
                    SDL_RenderFillRect(ge->getRenderer(), &rect);
                }
            }
        }
    }

}
